﻿/**
 * Peter
 * Created by: Peter Development Team
 *    http://peter.codeplex.com/
 * 
 * GNU General Public License version 2 (GPLv2)
 *    http://peter.codeplex.com/license
 *
 *  This code is provided on an AS IS basis, with no WARRANTIES,
 *  CONDITIONS or GUARANTEES of any kind.
 *
 **/

using System;
using System.Diagnostics;

namespace Peter.Logic.SourceControl
{
   /// <summary>
   /// Git operations for peter.
   /// </summary>
   public class PeterGit
   {
      #region Fields

      private string m_LastMessage;

      /// <summary>
      /// The git success message.
      /// </summary>
      public const string SUCCESS = "Success!";

      /// <summary>
      /// The name of the git executable.
      /// </summary>
      public const string GIT_EXE = "git.exe";

      #endregion

      #region Setup

      /// <summary>
      /// Initializes a new git for the given directory.
      /// </summary>
      /// <param name="baseDirectory">Base git directory.</param>
      public PeterGit (string baseDirectory)
      {
         this.GitExe = GIT_EXE;
         this.BaseDirectory = baseDirectory;
      }

      #endregion

      #region Properties

      /// <summary>
      /// Gets the base git directory.
      /// </summary>
      public string BaseDirectory { get; private set; }

      /// <summary>
      /// Gets or Sets the path to the git executable to use.
      /// </summary>
      public string GitExe { get; set; }

      #endregion

      #region Methods

      /// <summary>
      /// Initializes a git repository in the base directory.
      /// </summary>
      /// <returns>True if successful, otherwise false.</returns>
      public bool Init ()
      {
         var psInfo = new ProcessStartInfo (this.GitExe, "init");
         var process = this.CreateProcess (psInfo);
         process.Start ();
         process.WaitForExit ();
         return this.m_LastMessage == SUCCESS;
      }

      /* git status --porcelain */

      /// <summary>
      /// Creates a new process with output redirected.
      /// </summary>
      /// <param name="psInfo">Process start info.</param>
      /// <returns>The newly created process.</returns>
      private Process CreateProcess (ProcessStartInfo psInfo)
      {
         var process = new Process { StartInfo = psInfo };
         process.OutputDataReceived += HandleOutput;
         process.ErrorDataReceived += HandleError;
         process.BeginOutputReadLine ();
         process.BeginErrorReadLine ();
         return process;
      }

      /// <summary>
      /// Handles any standard output from a process.
      /// </summary>
      /// <param name="sender">The process.</param>
      /// <param name="e">DataReceivedEventArgs</param>
      private void HandleOutput (object sender, DataReceivedEventArgs e)
      {
         if (!string.IsNullOrEmpty (e.Data))
         {
            Console.WriteLine (e.Data);
            this.m_LastMessage = e.Data;
         }
      }

      /// <summary>
      /// Handles any error output from a process.
      /// </summary>
      /// <param name="sender">The process.</param>
      /// <param name="e">DataReceivedEventArgs</param>
      private static void HandleError (object sender, DataReceivedEventArgs e)
      {
         if (!string.IsNullOrEmpty (e.Data))
            Console.Error.WriteLine (e.Data);
      }

      #endregion
   }
}
